import Vue from 'vue'
import store from '@/store'
import { notification } from 'ant-design-vue'

// 注册一个全局自定义复制指令 `v-copy`
Vue.directive('copy', {
  bind (el, { value }) {
    el.$value = value
    el.handler = () => {
      el.style.position = 'relative'
      if (!el.$value) {
        // 值为空的时候，给出提示
        notification.warn({ message: '无复制内容' })
        return
      }
      // 动态创建 textarea 标签
      const textarea = document.createElement('textarea')
      // 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘，同时将 textarea 移出可视区域
      textarea.readOnly = 'readonly'
      textarea.style.position = 'absolute'
      textarea.style.top = '0px'
      textarea.style.left = '-9999px'
      textarea.style.zIndex = '-9999'
      // 将要 copy 的值赋给 textarea 标签的 value 属性
      textarea.value = el.$value
      // 将 textarea 插入到 el 中
      el.appendChild(textarea)
      // 兼容IOS 没有 select() 方法
      if (textarea.createTextRange) {
        textarea.select() // 选中值并复制
      } else {
        textarea.setSelectionRange(0, el.$value.length)
        textarea.focus()
      }
      const result = document.execCommand('Copy')
      if (result) {
        notification.success({ message: '复制成功' })
      }
      el.removeChild(textarea)
    }
    el.addEventListener('click', el.handler) // 绑定点击事件
  },
  // 当传进来的值更新的时候触发
  componentUpdated (el, { value }) {
    el.$value = value
  },
  // 指令与元素解绑的时候，移除事件绑定
  unbind (el) {
    el.removeEventListener('click', el.handler)
  }
})


/**
 * Action 权限指令
 * 指令用法：
 *  - 在需要控制 action 级别权限的组件上使用 v-action:[method] , 如下：
 *    <i-button v-action:add >添加用户</a-button>
 *    <a-button v-action:delete>删除用户</a-button>
 *    <a v-action:edit @click="edit(record)">修改</a>
 *
 *  - 当前用户没有权限时，组件上使用了该指令则会被隐藏
 *  - 当后台权限跟 pro 提供的模式不同时，只需要针对这里的权限过滤进行修改即可
 *
 *  @see https://github.com/vueComponent/ant-design-vue-pro/pull/53
 */
Vue.directive('action', {
  inserted: function (el, binding, vnode) {
    // debugger
    const actionName = binding.expression
    const roles = store.getters.roles
    const elVal = vnode.context.$route.meta.permission
    const permissionId = elVal instanceof String && [elVal] || elVal
    roles.permissions.forEach(p => {
      if (!permissionId.includes(p.permissionId)) {
        return
      }
      if (p.actionList && !p.actionList.includes(actionName)) {
        el.parentNode && el.parentNode.removeChild(el) || (el.style.display = 'none')
      }
    })
  }
})

const toggleIcon = (el, disable, loadingElement) => {
  if (!disable) { // 关闭时取消 loading
    loadingElement.remove()
    return
  }
  if (el.prepend) {
    el.prepend(loadingElement)
  } else {
    el.insertBefore(loadingElement, el.firstChild)
  }
}
/**
 * @directive v-single-click
 * @desc 防止重复点击指令 ****注意如果要传递参数，需要采用箭头函数的形式传入要防重的函数，最后会返回一个 promiseDone 方法来手动结束防重*****
 * @param { promise } binding.value - 传入要异步执行的方法
 * @param { boolean } binding.arg - true 有 icon 图标，false 没有
 * */
Vue.directive('single-click', {
  bind (el, binding) {
    let disable = false
    const func = binding.value // 接收任意表达式
    const icon = binding.arg || false
    if (!func) {
      throw new Error('v-single-click not define bind function')
    }
    const getLoadingElement = (() => {
      let loadingElement = null
      return function () {
        if (!loadingElement) {
          loadingElement = document.createElement('i')
          loadingElement.setAttribute('class', 'anticon anticon-loading')
          loadingElement.style.marginRight = '6px'
          // 转圈 loading 样式
          loadingElement.innerHTML = '' +
            '<svg viewBox="0 0 1024 1024" data-icon="loading" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="anticon-spin">' +
            '<path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"></path>' +
            '</svg>'
        }
        return loadingElement
      }
    })()

    const handleLoadingIcon = () => {
      if (icon) {
        toggleIcon(el, disable, getLoadingElement())
      }
    }
    const promiseOn = () => {
      el.disabled = true
      disable = true
      handleLoadingIcon()
    }
    const promiseDone = () => {
      el.disabled = false
      disable = false
      handleLoadingIcon()
    }
    const singleClickHandle = () => {
      if (disable) return
      promiseOn()
      try {
        const result = func(promiseDone)
        if (result && result.then) { // 判断是否 promise
          result.finally(promiseDone)
        }
      } catch (e) {
        console.error(e)
        promiseDone()
      }
    }
    el.onclick = singleClickHandle
  }
})

